package com.navi.loaddata.loadhis;

import com.navi.loaddata.core.gpEntity.MProdD;
import com.navi.loaddata.core.gpEntity.MppLayoutD;
import com.navi.loaddata.core.gpEntity.MppLayoutPnlD;
import com.navi.loaddata.core.oracleEntity.CtPosmmgpairproduct;
import com.navi.loaddata.core.oracleEntity.Productspec;
import com.navi.loaddata.core.repository.impl.GreenPlumRepositoryImpl;
import com.navi.loaddata.core.repository.impl.OracleRepositoryImpl;
import com.navi.loaddata.pojo.LayoutDTO;
import com.navi.loaddata.pojo.ProdDTO;
import com.navi.loaddata.utils.SaveEtlPoint;
import java.math.BigInteger;
import java.util.HashSet;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;


@Service
@Transactional(transactionManager = "secondaryPlatformTransactionManager", rollbackFor = Exception.class)
/**
 * 同步mpp_layout_d和mpp_layout_pnl_d
 *
 * @author Matthew
 */
public class LoadLayout {

  private Logger logger = LoggerFactory.getLogger(this.getClass());

  @Autowired
  private OracleRepositoryImpl dao3;
  @Autowired
  private GreenPlumRepositoryImpl dao2;
  @Autowired
  private SaveEtlPoint saveEtlPoint;


//  @Scheduled(cron = "0 0/10 * * * ?")
  @Scheduled(cron = "5 * * * * ?")
  public void syncLayout() {
    try {
      this.loadLayoutFromMes();
    } catch (Exception e) {
      logger.error("同步layout异常", e);
    }
  }

  public void loadLayoutFromMes() {

    /**
     * 1.从dm.mpp_layout_pnl_d获取上一次更新时间
     * 2.在CtPosmmgpairproduct中查找大于上一次更新时间的layout信息
     * 3.如果ctPosmmgpairproductList.size()等于0 return
     * 4.遍历ctPosmmgpairproductList，将layout的信息存入mpp_layout_pnl_d表中
     * 5.同时保存layout的 factoryname + productspecname + productspecversion 信息等待查询layout信息准备存入mpp_layout_d中
     * 6.同时保存prod的信息，准备更新m_prod_d表
     */


    LocalDateTime etlStart = LocalDateTime.now();
    Timestamp chotTime = null;
    List<CtPosmmgpairproduct> ctPosmmgpairproductList;
    logger.info("开始扫描 --> mpp_layout_pnl_d");
    List chotList = dao2.findBySQL("SELECT max(evt_timestamp) FROM dm.mpp_layout_pnl_d WHERE evt_cate = 'ETLL'");
    if (chotList.size() > 0) {
      chotTime = (Timestamp)chotList.get(0);
    }
    logger.info("当前更新时间:" + chotTime);

    if (chotTime != null) {
      ctPosmmgpairproductList = dao3.list(CtPosmmgpairproduct.class,
          "FROM CtPosmmgpairproduct WHERE lasteventtime >to_date('" + chotTime.toString().substring(0, 19)
              + "','yyyy/mm/dd HH24:MI:SS')");
    } else {
      ctPosmmgpairproductList = dao3.list(CtPosmmgpairproduct.class,
          "FROM CtPosmmgpairproduct WHERE lasteventtime >to_date('" + chotTime.toString().substring(0, 19)
              + "','yyyy/mm/dd HH24:MI:SS')");
    }
    if (ctPosmmgpairproductList.size() == 0) {
      return;
    }

    Set<ProdDTO> prodDTOS = new HashSet<>();
    Set<LayoutDTO> layoutDTOS = new HashSet<>();
    logger.info("开始同步表mpp_layout_pnl_d");
    ctPosmmgpairproductList.forEach(layout -> {
      String factoryName = layout.getFactoryname();
      String productSpecName = layout.getProductspecname();
      String productSpecVersion = layout.getProductspecversion();

      //存子表
      try {
        double startx = Double.valueOf(layout.getStartx() == null ? "0" : layout.getStartx()) / 1000;
        double starty = Double.valueOf(layout.getStarty() == null ? "0" : layout.getStarty()) / 1000;
        double endx = Double.valueOf(layout.getEndx() == null ? "0" : layout.getEndx()) / 1000;
        double endy = Double.valueOf(layout.getEndy() == null ? "0" : layout.getEndy()) / 1000;
        double width = getWidOrHei(endx, startx);
        double heigh = getWidOrHei(endy, starty);
        String layoutId = factoryName + "&" + productSpecName + "&" + productSpecVersion;
        String panelNo = layout.getPanelposition();
        MppLayoutPnlD mppLayoutPnlD = new MppLayoutPnlD();
        mppLayoutPnlD.setLayoutId(layoutId);
        mppLayoutPnlD.setPanelNo(Integer.parseInt(panelNo));
        String panelId = getPanelIdByNo(Integer.parseInt(layout.getPanelposition()));
        mppLayoutPnlD.setUnqSeqId(UUID.randomUUID().toString().replace("-", "").substring(0, 25));
        mppLayoutPnlD.setEtlTimestamp(Timestamp.valueOf(LocalDateTime.now()));
        mppLayoutPnlD.setEtlEventNode(InetAddress.getLocalHost().getHostAddress());
        mppLayoutPnlD.setEtlEventName(InetAddress.getLocalHost().getHostName());
        mppLayoutPnlD.setEtlEvtSeqId(UUID.randomUUID().toString().replace("-", "").substring(0, 30));
        mppLayoutPnlD.setxCoord(startx);
        mppLayoutPnlD.setxCoordCut(startx);
        mppLayoutPnlD.setyCoord(starty);
        mppLayoutPnlD.setyCoordCut(starty);
        mppLayoutPnlD.setxAxisLength(width);
        mppLayoutPnlD.setxAxisLengthCut(width);
        mppLayoutPnlD.setyAxisLength(heigh);
        mppLayoutPnlD.setyAxisLengthCut(heigh);
        mppLayoutPnlD.setPanelId(panelId);
        mppLayoutPnlD.setLayoutDsc(panelId);
        mppLayoutPnlD.setMrrLoc(panelId);
        mppLayoutPnlD.setPosDsc(panelId);
        mppLayoutPnlD.setLayoutCate("S");
        mppLayoutPnlD.setRotationAngle(0);
        mppLayoutPnlD.setEvtCate("ETLL");
        mppLayoutPnlD.setValidFlg("Y");
        mppLayoutPnlD.setEvtTimestamp(layout.getLasteventtime());
        mppLayoutPnlD.setEvtUser(layout.getLasteventuser());
        dao2.update(mppLayoutPnlD);
        logger.info("同步layoutId:{} - panelNo:{}", layoutId, panelNo);
      } catch (UnknownHostException e) {
        logger.error("获取LocalHost异常:", e);
      }

      List<MppLayoutD> isExist = dao2.list(MppLayoutD.class, "FROM MppLayoutD WHERE layoutId = ?",
          factoryName + "&" + productSpecName + "&" + productSpecVersion);
      if (isExist.size() > 0) {
        return;
      }
      ProdDTO prodDTO = new ProdDTO();
      prodDTO.setProductspecname(productSpecName);
      prodDTO.setLayout(factoryName + "&" + productSpecName + "&" + productSpecVersion);
      prodDTO.setFactoryName(factoryName);
      prodDTOS.add(prodDTO);

      LayoutDTO layoutDTO = new LayoutDTO();
      layoutDTO.setFactoryName(factoryName);
      layoutDTO.setProductSpecName(productSpecName);
      layoutDTO.setProductspecVersion(productSpecVersion);
      layoutDTOS.add(layoutDTO);
    });

    logger.info("共更新LayoutPnl:{}条数据", ctPosmmgpairproductList.size());

    StringBuffer sb = new StringBuffer();
    if (layoutDTOS.size() > 0) {
      layoutDTOS.forEach(lp ->
          sb.append("( ").append("factoryname='").append(lp.getFactoryName()).append("' ")
              .append(" AND productspecname='").append(lp.getProductSpecName()).append("' ")
              .append(" AND productspecversion='").append(lp.getProductspecVersion()).append("' ")
              .append(" ) OR")
      );
      String hql = "From Productspec where 1=1 " + "and" + sb.toString();
      List<Productspec> productspecs = dao3.find(Productspec.class, hql.substring(0, hql.length() - 3));
      productspecs.forEach(ps -> {
        List<CtPosmmgpairproduct> posmmgpairproducts = dao3.list(CtPosmmgpairproduct.class,
            "FROM CtPosmmgpairproduct WHERE factoryname = ? AND productspecname = ? AND productspecversion = ?",
            ps.getFactoryname(), ps.getProductspecname(), ps.getProductspecversion());
        int size = 0;
        if (posmmgpairproducts != null && posmmgpairproducts.size() > 0) {
          size = posmmgpairproducts.size();
        }
        if (null != posmmgpairproducts && posmmgpairproducts.size() <= 0) {
          return;
        }
        List layoutKeys = dao2.findBySQL("SELECT nextval('m_layout_d_key_seq')");
        BigInteger bi = (BigInteger) layoutKeys.get(0);
        MppLayoutD mppLayoutD = new MppLayoutD();
        mppLayoutD.setLayoutKey(bi.intValue());
        mppLayoutD.setUnqSeqId(UUID.randomUUID().toString().replace("-", "").substring(0, 25));
        mppLayoutD.setEtlTimestamp(Timestamp.valueOf(LocalDateTime.now()));
        try {
          mppLayoutD.setEtlEventNode(InetAddress.getLocalHost().getHostAddress());
          mppLayoutD.setEtlEventName(InetAddress.getLocalHost().getHostName());
        } catch (UnknownHostException e) {
          e.printStackTrace();
        }
        mppLayoutD.setEtlEvtSeqId(UUID.randomUUID().toString().replace("-", "").substring(0, 30));
        mppLayoutD.setTotalCnt(size);
        mppLayoutD.setEvtCate("ETLL");
        mppLayoutD.setLayoutId(ps.getFactoryname() + "&" + ps.getProductspecname() + "&" + ps.getProductspecversion());
        mppLayoutD.setLayoutDsc(ps.getDescription());
        mppLayoutD.setEvtTimestamp(ps.getLastupdatetime());
        mppLayoutD.setValidFlg("Y");
        dao2.update(mppLayoutD);
        logger.info("新增layoutId:{}", ps.getFactoryname() + "&" + ps.getProductspecname() + "&" + ps.getProductspecversion());
      });

      logger.info("共更新Layout:{}条数据", productspecs.size());

      prodDTOS.forEach(pp -> {
        List<MProdD> prodDS = dao2.list(MProdD.class, "from MProdD where prodId = ? and shopId = ? ", pp.getProductspecname(), pp.getFactoryName());
        if (prodDS != null && prodDS.size() > 0) {
          prodDS.forEach(prod -> {
            prod.setLayoutId(pp.getLayout());
            prod.setEtlTimestamp(Timestamp.valueOf(LocalDateTime.now()));
            prod.setEvtCate("ETLL");
            dao2.update(prod);
          });
        }
      });

      logger.info("共更新Product:{}条数据", prodDTOS.size());

      saveEtlPoint.save2etlLayout(etlStart, productspecs);
    }

  }

  private double getWidOrHei(double x_s, double x_e) {

    if (x_e > 0 && x_s > 0) {
      double x_sta = Math.abs(x_s);
      double x_end = Math.abs(x_e);
      BigDecimal bg = new BigDecimal(Math.abs(x_end - x_sta));
      return bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    } else if (x_e > 0 && x_s < 0) {
      double x_sta = Math.abs(x_s);
      double x_end = Math.abs(x_e);
      BigDecimal bg = new BigDecimal(Math.abs(x_end + x_sta));
      return bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    } else if (x_e < 0 && x_s < 0) {
      double x_sta = Math.abs(x_s);
      double x_end = Math.abs(x_e);
      BigDecimal bg = new BigDecimal(Math.abs(x_sta - x_end));
      return bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    } else if (x_e < 0 && x_s > 0) {
      double x_sta = Math.abs(x_s);
      double x_end = Math.abs(x_e);
      BigDecimal bg = new BigDecimal(Math.abs(x_end + x_sta));
      return bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    return 0;

  }

  private String getPanelIdByNo(int panelNo) {
    String panelId = String.format("%02d", panelNo);
    return panelId;
  }

}
